package com.sneakxy.mybatis.commons.repository.support;

import java.lang.reflect.Method;

import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.NamedQueries;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.QueryLookupStrategy;
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.data.repository.query.RepositoryQuery;

import com.sneakxy.mybatis.commons.orm.MybatisEntityManager;
import com.sneakxy.mybatis.commons.repository.query.MybatisQueryMethod;

/**
 * @author 潜行的青衣
 */
public class MybatisQueryLookupStrategy implements QueryLookupStrategy {
	
	private Key key;
	
	private QueryMethodEvaluationContextProvider evaluationContextProvider;
	
	private Object mapper;
	
	private MybatisEntityManager mybatisEntityManager;
	
	public MybatisQueryLookupStrategy(
			Object mapper, MybatisEntityManager mybatisEntityManager,
			Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) {
		this.mapper = mapper;
		this.key = key;
		this.evaluationContextProvider = evaluationContextProvider;
		this.mybatisEntityManager = mybatisEntityManager;
	}
	
	/* (non-Javadoc)
	 * @see org.springframework.data.repository.query.QueryLookupStrategy#resolveQuery(java.lang.reflect.Method, org.springframework.data.repository.core.RepositoryMetadata, org.springframework.data.projection.ProjectionFactory, org.springframework.data.repository.core.NamedQueries)
	 */
	@Override
	public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, ProjectionFactory factory,
			NamedQueries namedQueries) {
		AbstractMybatisRepositoryQuery repositoryQuery = null;
		MybatisQueryMethod queryMethod = new MybatisQueryMethod(method, metadata, factory, mybatisEntityManager);
		if(queryMethod.isMapperType()) {
			repositoryQuery = new MybatisMapperRepositoryQuery(mybatisEntityManager, queryMethod, mapper);
		} else {
			if(queryMethod.hasStatement()) {
				//xmlQuery
				repositoryQuery = new MybatisXmlMapperRepositoryQuery(mybatisEntityManager, queryMethod);
			} else {
				//NamedQuery
				repositoryQuery = new MybatisNamedRepositoryQuery(mybatisEntityManager, queryMethod, namedQueries);
			}
		}
		try {
			repositoryQuery.afterPropertiesSet();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return repositoryQuery;
	}

	public Object getMapper() {
		return mapper;
	}

	public Key getKey() {
		return key;
	}

	public QueryMethodEvaluationContextProvider getEvaluationContextProvider() {
		return evaluationContextProvider;
	}

	public MybatisEntityManager getMybatisEntityManager() {
		return mybatisEntityManager;
	}

}
